package com.hbx.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.hbx.auth.AuthCacheService;
import com.hbx.constant.CachePrefixContent;
import com.hbx.constant.TableEnum;
import com.hbx.logs.annotation.MarkLog;
import com.hbx.logs.OperaTypeEnum;
import com.hbx.dto.anno.InsertOrUpdateDto;
import com.hbx.exception.RspException;
import com.hbx.model.Announcement;
import com.hbx.mapper.AnnouncementMapper;
import com.hbx.model.Rank;
import com.hbx.model.User;
import com.hbx.service.AnnouncementService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hbx.service.RankService;
import com.hbx.service.UserRankService;
import com.hbx.service.UserService;
import com.hbx.task.CompletableFutureService;
import com.hbx.utils.CacheUtils;
import com.hbx.utils.Result;
import com.hbx.vo.PublicUserVo;
import com.hbx.vo.RankVo;
import com.hbx.vo.anno.AnnoVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * <p>
 * 系统公告表 服务实现类
 * </p>
 *
 * @author hbx
 * @since 2022-01-27
 */
@Service
public class AnnouncementServiceImpl extends ServiceImpl<AnnouncementMapper, Announcement> implements AnnouncementService {

    @Autowired
    private CacheUtils cacheUtils;

    @Autowired
    private AnnouncementMapper announcementMapper;

    @Autowired
    private UserService userService;

    @Autowired
    private UserRankService userRankService;

    @Autowired
    private RankService rankService;

    @Autowired
    private CompletableFutureService futureService;

    /**
     * 获得弹出公告信息
     * @param r
     */
    @Override
    public void getAnnoCommendInfo(Result r) {
        User user = AuthCacheService.getUser();
        QueryWrapper<Announcement> wrapper = new QueryWrapper<>();
        wrapper.eq("anno_is_commond",1);
        Announcement one = announcementMapper.selectOne(wrapper);
        // 没有弹出公告
        if (ObjectUtils.isEmpty(one)){
            r.setCode(202);
            return;
        }
        // 有
        Set<Object> members = cacheUtils.getSetMembers(CachePrefixContent.PLAT_ACCO_INFO + one.getId());
        // 集合中为空,或者不包含该用户
        if (CollectionUtils.isEmpty(members) || !members.contains(user.getUserId())){
            AnnoVo vo = new AnnoVo();
            BeanUtils.copyProperties(one, vo);
            // 处理数据
            String annoContent = one.getAnnoContent();
            if (StringUtils.hasLength(annoContent)){
                String[] strings = annoContent.split("。");
                if (!ObjectUtils.isEmpty(strings)){
                    vo.setAnnoContentList(Arrays.asList(strings));
                }
            }
            Integer adminId = one.getAnnoAdminId();
            if (!ObjectUtils.isEmpty(adminId)){
                User admin = userService.getById(adminId);
                if (!ObjectUtils.isEmpty(admin)){
                    PublicUserVo userVo = new PublicUserVo();
                    userVo.setUserId(adminId);
                    userVo.setUserName(admin.getLoginName());
                    userVo.setAvatar(admin.getAvator());
                    List<Rank> userRanks = rankService.getRankList(admin.getUserId());
                    if (!CollectionUtils.isEmpty(userRanks)){
                        List<RankVo> list = new ArrayList<>();
                        userRanks.stream().forEach(rank -> {
                            RankVo rankVo = new RankVo();
                            BeanUtils.copyProperties(rank, rankVo);
                            list.add(rankVo);
                        });
                        userVo.setRankList(list);
                    }
                    vo.setUser(userVo);
                }
            }
            // 返回数据
            r.setCode(200).setData(vo);
            return;
        }
        // 集合中包含用户
        r.setCode(202);
    }

    /**
     * 确认收到公告
     * @param annoId
     */
    @Override
    public void knownAnno(Integer annoId,Result r) {
        User user = AuthCacheService.getUser();
        cacheUtils.add(CachePrefixContent.PLAT_ACCO_INFO + annoId, new Integer[]{user.getUserId()});
        r.setCode(200);
    }

    /**
     * 获得所有公告信息
     * @param r
     */
    @Override
    public void getAnnoList(Result r) {
        QueryWrapper<Announcement> queryWrapper = new QueryWrapper<>();
        queryWrapper.orderByDesc("anno_is_commond").orderByDesc("anno_publish_time");
        List<Announcement> announcements = announcementMapper.selectList(queryWrapper);
        if (CollectionUtils.isEmpty(announcements)){
            r.setCode(200).setData(new ArrayList<>());
            return;
        }
        List<AnnoVo> list = new ArrayList<>();
        announcements.stream().forEach(a -> {
            AnnoVo vo = new AnnoVo();
            BeanUtils.copyProperties(a, vo);
            // 处理数据
            String annoContent = a.getAnnoContent();
            if (StringUtils.hasLength(annoContent)){
                String[] strings = annoContent.split("。");
                if (!ObjectUtils.isEmpty(strings)){
                    vo.setAnnoContentList(Arrays.stream(strings).map(s -> s + "。").collect(Collectors.toList()));
                }
            }

            Integer adminId = a.getAnnoAdminId();
            if (!ObjectUtils.isEmpty(adminId)){
                User admin = userService.getById(adminId);
                if (!ObjectUtils.isEmpty(admin)){
                    PublicUserVo userVo = new PublicUserVo();
                    userVo.setUserId(adminId);
                    userVo.setUserName(admin.getLoginName());
                    userVo.setAvatar(admin.getAvator());
                    List<Rank> userRanks = rankService.getRankList(admin.getUserId());
                    if (!CollectionUtils.isEmpty(userRanks)){
                        List<RankVo> ranklist = new ArrayList<>();
                        userRanks.stream().forEach(rank -> {
                            RankVo rankVo = new RankVo();
                            BeanUtils.copyProperties(rank, rankVo);
                            ranklist.add(rankVo);
                        });
                        userVo.setRankList(ranklist);
                    }
                    vo.setUser(userVo);
                }
            }
            list.add(vo);
        });
        r.setCode(200).setData(list);
    }

    /**
     * 删除公告
     * @param annoId
     * @param r
     */
    @Override
    @MarkLog(operate = OperaTypeEnum.DELETE, tables = TableEnum.ANNOUNCEMENT, desc = "管理员删除公告")
    public void removeAnno(Integer annoId, Result r) {
        int result = announcementMapper.deleteById(annoId);
        if (result != 1){
            r.setCode(201).setMsg("删除失败");
            return;
        }
        r.setCode(200).setMsg("删除成功");
        // 删掉redis中的key
        futureService.runAsyncTask(() -> {
            cacheUtils.removeKey(CachePrefixContent.PLAT_ACCO_INFO + annoId);
        });
    }

    /**
     * 发布或修改公告
     * @param dto
     * @param r
     */
    @Override
    @Transactional
    @MarkLog(operate = OperaTypeEnum.UPDATE, tables = TableEnum.ANNOUNCEMENT, desc = "发布或修改公告")
    public void insertOrUpdateAnno(InsertOrUpdateDto dto, Result r) {
        Boolean flag = false;
        Integer count = 0;
        // 操作的菜单是全局展示的
        if(dto.getAnnoIsCommond() != null && dto.getAnnoIsCommond() == 1){
            flag = true;
            QueryWrapper<Announcement> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("anno_is_commond",1);
            List<Announcement> list = announcementMapper.selectList(queryWrapper);
            if (list != null){
                count = list.size();
            }
        }
        Integer id = dto.getId();
        String title = dto.getAnnoTitle();
        User user = AuthCacheService.getUser();
        Announcement announcement = new Announcement();
        BeanUtils.copyProperties(dto, announcement);
        announcement.setAnnoPublishTime(new Date());
        announcement.setAnnoAdminId(user.getUserId());
        Integer result = 0;
        if(id == null){
            QueryWrapper<Announcement> wrapper = new QueryWrapper<>();
            wrapper.eq("anno_title",title.trim());
            List<Announcement> announcementList = announcementMapper.selectList(wrapper);
            if (!CollectionUtils.isEmpty(announcementList)){
                r.setCode(201).setMsg("公告标题已存在,添加失败");
                return;
            }
            // 新增
            result = announcementMapper.insert(announcement);
        } else {
            result = announcementMapper.updateById(announcement);
        }
        if(flag && result == 1 &&  count > 0){
            // 修改其他的展示情况
            int update = announcementMapper.updateOtherCommend(announcement.getId(), 0);
            if (update <= 0){
                throw new RspException("操作失败,请重新尝试");
            }
        }

        if (result != 1){
            r.setCode(201).setMsg("操作失败,请重新尝试");
            return;
        }
        r.setCode(200).setMsg("操作成功");
    }
}
